import json
from decimal import Decimal

from django import http
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import transaction
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django_redis import get_redis_connection

from apps.address.models import Address
from apps.goods.models import FoodsChannel
from apps.orders.models import OrderInfo, OrderFoods
from utils.response_code import RETCODE


class OrderView(LoginRequiredMixin,View):
    """结算订单"""

    def get(self, request):
        """提供订单结算页面"""
        # 获取登录用户
        user = request.user
        # 查询地址信息
        try:
            addresses = Address.objects.filter(user=request.user, is_deleted=False)
            # print(addresses)
        except Address.DoesNotExist:
            return http.HttpResponseBadRequest('not found')
        # 从redis购物车里查询出被勾选的商品信息
        redis_conn = get_redis_connection('carts')
        # 取出数据
        redis_cart = redis_conn.hgetall('carts_%s' % user.id)
        cart = {}
        # 取出勾选的数据对比cart_selected看这个数据是否存在 转int防止报错
        for food_id in redis_cart:
            cart[int(food_id)] = int(redis_cart[food_id])

        # 准备初始值
        total_count = 0
        total_amount = Decimal(0.00)  # 总价
        # 查询商品信息
        foods = FoodsChannel.objects.filter(id__in=cart.keys())
        for food in foods:
            food.count = cart[food.id]
            food.amount = food.count * food.price
            # 计算总数量和总金额
            total_count += food.count
            total_amount += food.count * food.price

        # 补充运费
        # freight = Decimal('10.00')

        # 渲染界面
        context = {
            'username':request.user.username,
            'addresses': addresses,
            'foods': foods,
            'total_count': total_count,
            'total_amount': total_amount,#总价
            # 'freight': freight,
            # 'payment_amount': total_amount# 总价
        }

        return render(request, 'order_cart.html',context)


class OrderCommitView(LoginRequiredMixin,View):
    """订单提交"""
    def post(self, request):
        """保存订单信息和订单商品信息"""
        # 获取当前要保存的订单数据
        json_dict = json.loads(request.body.decode())
        address_id = json_dict.get('address_id')
        pay_method = json_dict.get('pay_method')

        # 校验参数
        if not all([address_id, pay_method]):
            return http.HttpResponseBadRequest('缺少必传参数')
        # 判断address_id是否合法
        try:
            address = Address.objects.get(id=address_id)
            # 判断这个收货地址是否属于当前登录用户
            if address.user != request.user:
                # 如果不属于当前用户，那么返回错误信息信息
                return http.HttpResponseBadRequest('参数address_id错误')
        except Exception:
            return http.HttpResponseBadRequest('参数address_id错误')
        # 判断pay_method是否合法
        if int(pay_method) not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
            return http.HttpResponseBadRequest('参数pay_method错误')

        # 获取登录用户
        user = request.user
        # 生成订单编号：年月日时分秒+用户编号
        order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + '%09d' % user.id
        # 保存订单基本信息 OrderInfo（一）
        order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            total_count=0,
            total_amount=Decimal('0'),
            pay_method=pay_method,
            status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
            OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        )
        # 从redis读取购物车中被勾选的商品信息
        redis_conn = get_redis_connection('carts')
        redis_cart = redis_conn.hgetall('carts_%s' % user.id)
        carts = {}
        for food_id in redis_cart:
            carts[int(food_id)] = int(redis_cart[food_id])
        food_ids = carts.keys()

        # # 遍历购物车中被勾选的商品信息
        for food_id in food_ids:
            # 查询SKU信息
            food = FoodsChannel.objects.get(id=food_id)
        #     # 判断SKU库存
            food_count = carts[food.id]
        #     if sku_count > food.stock:
        #         return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '库存不足'})
        #
        #     # SKU减少库存，增加销量
        #     sku.stock -= sku_count
        #     sku.sales += sku_count
        #     sku.save()

            # 保存订单商品信息 OrderGoods（多）
            OrderFoods.objects.create(
                order=order,
                food=food,
                count=food_count,
                price=food.price,
            )

            # 保存商品订单中总价和总数量
            order.total_count += food_count
            order.total_amount += (food_count * food.price)
            order.save()

        # 清除购物车中已结算的商品
        pl = redis_conn.pipeline()
        pl.hdel('carts_%s' % user.id, *carts)
        pl.execute()

        # 响应提交订单结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '下单成功', 'order_id': order.order_id})

class OrderSuccessView(LoginRequiredMixin,View):

    def get(self, request):
        # 接收参数
        """提交订单成功"""
        user = request.user
        redis_conn = get_redis_connection('carts')
        # 取出数据
        redis_cart = redis_conn.hgetall('carts_%s' % user.id)
        cart = {}
        # 取出勾选的数据对比cart_selected看这个数据是否存在 转int防止报错
        for food_id in redis_cart:
            cart[int(food_id)] = int(redis_cart[food_id])

        order_id = request.GET.get('order_id')

        order = OrderInfo.objects.get(order_id=order_id)
        total_amount = order.total_amount
        #     print(e)
        # 准备初始值
        # total_count = 0
        # total_amount = Decimal(0.00)  # 总价
        # # 查询商品信息
        # foods = FoodsChannel.objects.filter(id__in=cart.keys())
        # for food in foods:
        #     food.count = cart[food.id]
        #     food.amount = food.count * food.price
        #     # 计算总数量和总金额
        #     total_count += food.count
        #     total_amount += food.count * food.price
        print(total_amount)


        context = {
            'order_id':order_id,
            'username':request.user.username,
            'phone': request.user.phone,
            'total_amount':total_amount
        }
        return render(request, 'order_success.html',context)